#ifndef __SESSION_H__
#define __SESSION_H__

#include <atomic>
#include <string>
#include <memory>
#include <queue>
#include <mutex>

#include <boost/asio.hpp>
#include <boost/asio/io_context.hpp>

#include "MsgNode.h"

class Server;

class Session: public std::enable_shared_from_this<Session>
{
public:
    Session(boost::asio::io_context& io_context, Server* server);

    void Start();
    void Send(const char* msg, size_t len, uint32_t msg_id);
    std::string GetSessionId() const { return _sessionId; }
    boost::asio::ip::tcp::socket& GetSocket() { return _socket; }

private:
    void _HandleRead(const boost::system::error_code& ec, size_t len, std::shared_ptr<Session> self_ptr);
    void _HandleWrite(const boost::system::error_code& ec, std::shared_ptr<Session> self_ptr);
    void _Close();

private:
    std::string _sessionId;
    boost::asio::ip::tcp::socket _socket;
    Server* _server;
    std::atomic_bool _b_closed;             // 是否关闭连接
    std::atomic_bool _b_head_parsed;        // 消息头是否解析完成
    std::unique_ptr<char[]> _read_buf;      // 读缓冲区
    std::shared_ptr<HeadNode> _head_node;   // 消息头缓冲区
    std::shared_ptr<RecvNode> _recv_node;   // 消息体缓冲区
    std::queue<std::shared_ptr<SendNode>> _send_queue; // 发送队列
    std::mutex _send_lock;                  // 发送队列锁
};

class LogicNode 
{
public:
    LogicNode(std::shared_ptr<Session> session, std::shared_ptr<RecvNode> recv_node)
    :_session(session)
    ,_recv_node(recv_node)
    {}

    std::shared_ptr<Session> _session;
    std::shared_ptr<RecvNode> _recv_node;
};


#endif // !__SESSION_H__
